﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JGSY.Tasks
{
    public class Interlocked1
    {
        // 共享变量，用于原子操作
        private static int sharedCounter = 0;
        private static long sharedLong = 0;
        private static int[] array = new int[10];
        private static MyClass myReference = new MyClass { Value = 100 };

        public static void Interlocked1001()
        {
            Console.WriteLine("=== Interlocked类原子操作演示 ===");

            // 演示基本原子操作
            RunBasicOperations();

            // 演示无锁计数器
            RunLockFreeCounter();

            // 演示数组元素的原子操作
            RunArrayOperations();

            // 演示引用类型的原子操作
            RunReferenceOperations();

            Console.WriteLine("\n所有示例执行完毕，按任意键退出...");
            Console.ReadKey();
        }

        static void RunBasicOperations()
        {
            Console.WriteLine("\n--- 基本原子操作 ---");

            // 原子递增
            int incrementResult = Interlocked.Increment(ref sharedCounter);
            Console.WriteLine($"Increment后的值: {incrementResult}");

            // 原子递减
            int decrementResult = Interlocked.Decrement(ref sharedCounter);
            Console.WriteLine($"Decrement后的值: {decrementResult}");

            // 原子加法
            int addResult = Interlocked.Add(ref sharedCounter, 5);
            Console.WriteLine($"Add(5)后的值: {addResult}");

            // 原子交换
            int exchangeResult = Interlocked.Exchange(ref sharedCounter, 100);
            Console.WriteLine($"Exchange(100)后的原值: {exchangeResult}, 新值: {sharedCounter}");

            // 原子比较并交换
            int compareExchangeResult = Interlocked.CompareExchange(ref sharedCounter, 200, 100);
            Console.WriteLine($"CompareExchange(200, 100)后的原值: {compareExchangeResult}, 新值: {sharedCounter}");

            // 64位长整型原子操作
            long longResult = Interlocked.Add(ref sharedLong, 1000);
            Console.WriteLine($"64位Add(1000)后的值: {sharedLong}");

            // 重置共享变量
            Interlocked.Exchange(ref sharedCounter, 0);
            Interlocked.Exchange(ref sharedLong, 0);
        }

        static void RunLockFreeCounter()
        {
            Console.WriteLine("\n--- 无锁计数器演示 ---");

            const int iterations = 1000000;
            var tasks = new Task[5];

            // 多个线程同时递增计数器
            for (int i = 0; i < 5; i++)
            {
                tasks[i] = Task.Run(() =>
                {
                    for (int j = 0; j < iterations; j++)
                    {
                        // 原子递增，无需锁
                        Interlocked.Increment(ref sharedCounter);
                    }
                });
            }

            Task.WaitAll(tasks);
            Console.WriteLine($"预期值: {iterations * 5}, 实际值: {sharedCounter}");
            Interlocked.Exchange(ref sharedCounter, 0); // 重置
        }

        static void RunArrayOperations()
        {
            Console.WriteLine("\n--- 数组元素的原子操作 ---");

            // 初始化数组
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = i;
            }

            // 原子更新数组元素
            var updateTask = Task.Run(() =>
            {
                for (int i = 0; i < 1000; i++)
                {
                    int index = i % array.Length;
                    Interlocked.Increment(ref array[index]);
                }
            });

            // 原子读取数组元素
            var readTask = Task.Run(() =>
            {
                for (int i = 0; i < 1000; i++)
                {
                    int index = i % array.Length;
                    int value = Interlocked.CompareExchange(ref array[index], 0, 0);
                    // CompareExchange with same value acts as atomic read
                }
            });

            Task.WaitAll(updateTask, readTask);

            Console.WriteLine("数组元素最终值:");
            for (int i = 0; i < array.Length; i++)
            {
                Console.Write($"{array[i]} ");
            }
            Console.WriteLine();
        }

        static void RunReferenceOperations()
        {
            Console.WriteLine("\n--- 引用类型的原子操作 ---");

            // 原子更新引用
            var updateTask = Task.Run(() =>
            {
                for (int i = 0; i < 10; i++)
                {
                    MyClass newRef = new MyClass { Value = i * 10 };
                    MyClass original = Interlocked.Exchange(ref myReference, newRef);
                    Console.WriteLine($"Exchange: 原值={original.Value}, 新值={newRef.Value}");
                }
            });

            // 原子比较并交换引用
            var compareTask = Task.Run(() =>
            {
                for (int i = 0; i < 5; i++)
                {
                    MyClass expected = myReference;
                    MyClass newRef = new MyClass { Value = expected.Value + 100 };

                    // 尝试原子更新，如果引用未被其他线程改变
                    MyClass actual = Interlocked.CompareExchange(ref myReference, newRef, expected);

                    if (actual == expected)
                    {
                        Console.WriteLine($"CompareExchange成功: {expected.Value} -> {newRef.Value}");
                    }
                    else
                    {
                        Console.WriteLine($"CompareExchange失败: 期望值={expected.Value}, 当前值={actual.Value}");
                    }
                }
            });

            Task.WaitAll(updateTask, compareTask);
        }
    }

    class MyClass
    {
        public int Value { get; set; }
    }
}
 
